<template>
  <canvas ref="canvasRef" class="border border-gray-300 rounded "></canvas>
</template>
<script setup lang="ts">
import { uploadImage } from '@/api/request';
import { drawLine, drawCircle } from '../utils/draw'

// 定义组件事件
const emit = defineEmits<{
  'drawing-complete': [{src: string, type: string}]
  'drawing-error': [error: string]
  'image-load-error': [error: string]
}>()

// 接收父组件传递的参数
const props = defineProps<{
  info: any,
  version: string
}>()

// canvas引用
const canvasRef = ref<HTMLCanvasElement | null>(null)
// 绘图上下文
const ctx = ref<CanvasRenderingContext2D | null>(null)
// 是否正在绘制
const isDrawing = ref(false)
// 绘图工具设置
const lineWidth = ref(3)
const strokeStyle = ref('#000000')
// 背景图片
const backgroundImage = ref<HTMLImageElement | null>(null)
// 图片加载状态
const imageLoaded = ref(false)
// 图片与canvas的比例
const scale = ref(1)

/**
 * 加载背景图片
 * @param src 图片路径
 * @returns Promise 返回加载结果的Promise
 */
/**
 * 加载背景图片并计算缩放比例
 * @param src 图片路径
 * @returns Promise 返回加载结果的Promise
 */
const loadImage = (src: string): Promise<HTMLImageElement> => {
  return new Promise((resolve, reject) => {
    const img = new Image()
    img.crossOrigin = 'anonymous';
    img.onload = () => {
      imageLoaded.value = true
      backgroundImage.value = img

      // 计算图片与canvas的比例
      if (canvasRef.value) {
        // 计算图片原始尺寸与canvas尺寸的比例
        const widthRatio = canvasRef.value.width / img.naturalWidth
        const heightRatio = canvasRef.value.height / img.naturalHeight
        // 使用较小的比例，确保图片完全显示在canvas中
        scale.value = Math.min(widthRatio, heightRatio)
        console.log('图片缩放比例:', scale.value)
      }
      resolve(img)
    }

    img.onerror = (e) => {
      imageLoaded.value = false
      reject(new Error('图片加载失败'))
    }

    img.src = src
  })
}

/**
 * 初始化canvas
 */
const initCanvas = async () => {
  if (!canvasRef.value) return

  const canvas = canvasRef.value
  ctx.value = canvas.getContext('2d')

  if (!ctx.value) {
    emit('drawing-error', '无法获取canvas上下文')
    return
  }

  // 设置画布大小
  canvas.width = 800
  canvas.height = 1066

  // 设置绘图样式
  ctx.value.lineJoin = 'round'
  ctx.value.lineCap = 'round'
  ctx.value.lineWidth = lineWidth.value * scale.value
  ctx.value.strokeStyle = strokeStyle.value

  // 初始化背景
  ctx.value.fillStyle = '#ffffff'
  ctx.value.fillRect(0, 0, canvas.width, canvas.height)

  // 如果有初始数据，绘制
  if (props.info) {
    drawFromInfo(props.info)
  }
}
/**
 * 清空画布
 */
const clearCanvas = () => {
  if (!ctx.value || !canvasRef.value) return

  ctx.value.fillStyle = '#ffffff'
  ctx.value.fillRect(0, 0, canvasRef.value.width, canvasRef.value.height)
}

/**
 * 根据info数据绘制图形
 * @param info 包含绘图数据的对象
 */
const drawFromInfo = async (info: any) => {

  // 优先检查info.img作为图片源
  if (info.img && !imageLoaded.value) {
    try {
      await loadImage(info.img)
      // 绘制背景图片
      if (backgroundImage.value && ctx.value && canvasRef.value) {
        // 清空画布，准备重新绘制
        clearCanvas()
        ctx.value.drawImage(backgroundImage.value, 0, 0, canvasRef.value.width, canvasRef.value.height)
      }
    } catch (error) {
      emit('image-load-error', error instanceof Error ? error.message : '图片加载失败')
      return
    }
  }

  try {
    // 绘制线条
    if (info.line && Array.isArray(info.line)) {
      info.line.forEach((line: any) => {
        if (!ctx.value) return
        const start = { x: line[0].x, y: line[0].y }
        const end = { x: line[1].x, y: line[1].y }
        const lineWidth = ctx.value.lineWidth
        const color = '#ff5252'
        // 使用draw.ts中的drawLine函数
        drawLine(ctx.value, start, end, lineWidth, color, scale.value)
      })
    }

    // 绘制关节点
    if (info.joint && Array.isArray(info.joint)) {
      info.joint.forEach((joint: any) => {
        if (!ctx.value || !joint) return
        // 使用draw.ts中的drawJoint函数绘制关节点
        const radius = ctx.value.lineWidth
        const lineWidth = ctx.value.lineWidth
        const color = '#ff5252'
        // 使用draw.ts中的drawJoint函数
        drawCircle(ctx.value, joint.x, joint.y, radius, lineWidth, color, scale.value)
      })
    }

    // 绘制辅助线
    if (info.assist_line && Array.isArray(info.assist_line)) {
      info.assist_line.forEach((line: any) => {
        if (!ctx.value) return
        const start = { x: line[0], y: line[1] }
        const end = { x: line[2], y: line[3] }
        const lineWidth = ctx.value.lineWidth
        const color = '#00ff7a'
        // 使用draw.ts中的drawLine函数
        drawLine(ctx.value, start, end, lineWidth, color, scale.value)
      })
    }

    // 绘制完成后触发事件
    if (canvasRef.value) {
      canvasRef.value.toBlob((blob) => {
        if (blob) {
          const file = new File([blob], `${Date.now()}.png`, {
            type: 'image/png',
          });

          let uploadUrl = 'https://physical-ai.grate9.com/lan/common/uploadImg'
          if (props.version === 'pro') {
            uploadUrl = 'https://physical-ai.grate9.com/pro/common/uploadImg'
          }
          uploadImage(uploadUrl, file, { sence: 'ai_physical' }).then(res => {
            console.log("🚀 ~ file: DrawingCanvas.vue:139 ~ res:", res)
            emit('drawing-complete',  {src: res.data.url, type: props.info!.type})
          })
        }
      })
    }
  } catch (error) {
    emit('drawing-error', error instanceof Error ? error.message : '未知错误')
  }
}

// 组件挂载时初始化
onMounted(() => {
  initCanvas()
})

// 暴露方法给父组件
defineExpose({
  clearCanvas,
  drawFromInfo,
  loadImage
})
</script>
